package com.cakeclient.Model;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import com.cakeclient.clientsoap.contract.ProductCategory;
import com.cakeclient.database.*;

import java.util.ArrayList;
import java.util.List;


public class CatalogCategory implements IDatabasable {
    private Long idDB = null;
    private Long remoteID;
    private String name;
    private String illustration;
    private String description;
    private List<Long> parentCategoryId = new ArrayList<Long>();
    private List<Long> childCategoriesId = new ArrayList<Long>();
    private List<Long> childProductTypeId = new ArrayList<Long>();
    private List<Long> childMenuTypeId = new ArrayList<Long>();

    private CatalogCategory(DataSource dataSource, Cursor cursor) {
        idDB = cursor.getLong(cursor.getColumnIndexOrThrow(ProductCategoryTable.ID));
        setRemoteID(cursor.getLong(cursor.getColumnIndexOrThrow(ProductTable.REMOTE_ID)));
        name = cursor.getString(cursor.getColumnIndexOrThrow(ProductCategoryTable.NAME));
        illustration = cursor.getString(cursor.getColumnIndexOrThrow(ProductCategoryTable.ILLUSTRATION));
        description = cursor.getString(cursor.getColumnIndexOrThrow(ProductCategoryTable.ILLUSTRATION));
        {
            //Recuperer les ids des Parents
            Cursor cursorp = dataSource.getMore(this, ProductCategory_has_ProductCategory.getInstance(), ProductCategory_has_ProductCategory.ID_PRODUCTCATEGORYCHILD);
            cursorp.moveToFirst();
            while (!cursorp.isAfterLast()) {
                this.getParentCategoryId().add(cursorp.getLong(cursorp.getColumnIndexOrThrow(ProductCategory_has_ProductCategory.ID_PRODUCTCATEGORYPARENT)));
                cursorp.moveToNext();
            }
            //Recuperer les ids des enfants Category
            cursorp.close();
            cursorp = dataSource.getMore(this, ProductCategory_has_ProductCategory.getInstance(), ProductCategory_has_ProductCategory.ID_PRODUCTCATEGORYPARENT);
            cursorp.moveToFirst();
            while (!cursorp.isAfterLast()) {
                this.getChildCategoriesId().add(cursorp.getLong(cursorp.getColumnIndexOrThrow(ProductCategory_has_ProductCategory.ID_PRODUCTCATEGORYCHILD)));
                cursorp.moveToNext();
            }
            //Recuperer les ids des enfants MenuTypeTable
            cursorp.close();
            cursorp = dataSource.getMore(this, MenuType_has_ProductCategory.getInstance(), MenuType_has_ProductCategory.ID_PRODUCTCATEGORY);
            cursorp.moveToFirst();
            while (!cursorp.isAfterLast()) {
                this.getChildMenuTypeId().add(cursorp.getLong(cursorp.getColumnIndexOrThrow(MenuType_has_ProductCategory.ID_MENUTYPE)));
                cursorp.moveToNext();
            }
            //Recuperer les ids des enfants ProductTypeTable
            cursorp.close();
            cursorp = dataSource.getMore(this, ProductType_has_ProductCategory.getInstance(), ProductType_has_ProductCategory.ID_PRODUCTCATEGORY);
            cursorp.moveToFirst();
            while (!cursorp.isAfterLast()) {
                this.getChildProductTypeId().add(cursorp.getLong(cursorp.getColumnIndexOrThrow(ProductType_has_ProductCategory.ID_PRODUCTTYPE)));
                cursorp.moveToNext();
            }
            cursorp.close();
        }

    }

    public CatalogCategory(String name, String description) {
        this.name = name;
        this.description = description;
    }

    public CatalogCategory(Context context, ProductCategory productCategory) {
        this.remoteID = Long.valueOf(productCategory.id);
        this.name = productCategory.name;
        this.illustration = productCategory.illustration;
        this.description = productCategory.description;
        if(productCategory.childProductCategoryId != null)
        for (Integer i : productCategory.childProductCategoryId) {
            this.addChildCategory(CatalogCategory.getOneFromRemoteID(context, Long.valueOf(i)));
        }
        if(productCategory.childProductTypeId != null)
        for (Integer i : productCategory.childProductTypeId) {
            this.addChildProductType(ProductType.getOneFromRemoteID(context, Long.valueOf(i)));
        }
        //TODO : MenuTypes
    }

    public CatalogCategory() {

    }

    public Long getRemoteID() {
        return remoteID;
    }

    private void setRemoteID(Long remoteID) {
        this.remoteID = remoteID;
    }

    public Long getIdDB() {
        return idDB;
    }

    public void addChildCategory(CatalogCategory catalogCategory) {
        if (catalogCategory != null)
            this.getChildCategoriesId().add(catalogCategory.getIdDB());
    }

    public void addChildProductType(ProductType productType) {
        if (productType != null)
            this.getChildProductTypeId().add(productType.getIdDB());
    }

    public void addChildMenuType(MenuType menuType) {
        this.getChildMenuTypeId().add(menuType.getIdDB());
    }

    public void addChildCategory(List<CatalogCategory> catalogCategories) {
        for (CatalogCategory catalogCategory : catalogCategories) {
            this.getChildCategoriesId().add(catalogCategory.getIdDB());
        }
    }

    public void addChildProductType(List<ProductType> productTypes) {
        for (ProductType productType : productTypes) {
            this.getChildProductTypeId().add(productType.getIdDB());
        }
    }

    public void addChildMenuType(List<MenuType> menuTypes) {
        for (MenuType menuType : menuTypes) {
            this.getChildMenuTypeId().add(menuType.getIdDB());
        }
    }


    public void setIdDB(Long idDB) {
        this.idDB = idDB;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getIllustration() {
        return illustration;
    }

    public void setIllustration(String illustration) {
        this.illustration = illustration;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public List<Long> getParentCategoryId() {
        return parentCategoryId;
    }

    public void setParentCategoryId(List<Long> parentCategoryId) {
        this.parentCategoryId = parentCategoryId;
    }

    public List<Long> getChildMenuTypeId() {
        return childMenuTypeId;
    }

    public void setChildMenuTypeId(List<Long> childMenuTypeId) {
        this.childMenuTypeId = childMenuTypeId;
    }

    public List<Long> getChildCategoriesId() {
        return childCategoriesId;
    }

    public void setChildCategoriesId(List<Long> childCategoriesId) {
        this.childCategoriesId = childCategoriesId;
    }

    public List<Long> getChildProductTypeId() {
        return childProductTypeId;
    }

    public void setChildProductTypeId(List<Long> childProductTypeId) {
        this.childProductTypeId = childProductTypeId;
    }

    @Override
    public ContentValues getValues() {
        ContentValues values = new ContentValues();
        values.put(ProductCategoryTable.NAME, this.name);
        values.put(ProductCategoryTable.REMOTE_ID, this.getRemoteID());
        values.put(ProductCategoryTable.ILLUSTRATION, this.illustration);
        values.put(ProductCategoryTable.DESCRIPTION, this.description);
        return values;
    }


    @Override
    public void saveToDatabase(Context context) {
        //Protection anti-doublons
        CatalogCategory bis = null;
        if (this.getIdDB() == null && this.getRemoteID() != null && (bis = CatalogCategory.getOneFromRemoteID(context, this.getRemoteID())) != null) {
            this.setIdDB(bis.getIdDB());
        }

        DataSource dataSource = new DataSource(context);
        dataSource.open();

        if (this.getIdDB() == null) {
            dataSource.insert(this, ProductCategoryTable.getInstance());
        } else {
            dataSource.update(this, ProductCategoryTable.getInstance());
            dataSource.delete(this, ProductCategory_has_ProductCategory.getInstance(), ProductCategory_has_ProductCategory.ID_PRODUCTCATEGORYPARENT);
            dataSource.delete(this, ProductType_has_ProductCategory.getInstance(), ProductType_has_ProductCategory.ID_PRODUCTCATEGORY);
            dataSource.delete(this, MenuType_has_ProductCategory.getInstance(), MenuType_has_ProductCategory.ID_PRODUCTCATEGORY);
        }
        {
            for (Long l : this.childCategoriesId) {
                dataSource.insert(ProductCategory_has_ProductCategory.getInstance(), l, this.getIdDB());
            }
            for (Long l : this.childProductTypeId) {
                dataSource.insert(ProductType_has_ProductCategory.getInstance(), l, this.getIdDB());
            }
            for (Long l : this.childMenuTypeId) {
                dataSource.insert(MenuType_has_ProductCategory.getInstance(), l, this.getIdDB());
            }
        }
        dataSource.close();
    }

    @Override
    public void removeFromDatabase(Context context) {
        if (this.getIdDB() != null) {
            DataSource dataSource = new DataSource(context);
            dataSource.open();
            dataSource.delete(this, ProductCategoryTable.getInstance());
            dataSource.delete(this, ProductCategory_has_ProductCategory.getInstance(), ProductCategory_has_ProductCategory.ID_PRODUCTCATEGORYCHILD);
            dataSource.delete(this, ProductCategory_has_ProductCategory.getInstance(), ProductCategory_has_ProductCategory.ID_PRODUCTCATEGORYPARENT);
            dataSource.delete(this, ProductType_has_ProductCategory.getInstance(), ProductType_has_ProductCategory.ID_PRODUCTCATEGORY);
            dataSource.delete(this, MenuType_has_ProductCategory.getInstance(), MenuType_has_ProductCategory.ID_PRODUCTCATEGORY);
            dataSource.close();
        }
    }

    public static CatalogCategory getOne(Context context, Long id) {
        DataSource dataSource = new DataSource(context);
        dataSource.open();
        Cursor cursor = dataSource.fetchOne(id, ProductCategoryTable.getInstance());
        cursor.moveToFirst();
        CatalogCategory item = null;
        while (!cursor.isAfterLast()) {
            item = new CatalogCategory(dataSource, cursor);
            cursor.moveToNext();
        }
        cursor.close();
        dataSource.close();
        return item;
    }

    public static CatalogCategory getOneFromRemoteID(Context context, Long id) {
        DataSource dataSource = new DataSource(context);
        dataSource.open();
        Cursor cursor = dataSource.fetchOneFromRemoteID(id, ProductCategoryTable.getInstance());
        cursor.moveToFirst();
        CatalogCategory item = null;
        while (!cursor.isAfterLast()) {
            item = new CatalogCategory(dataSource, cursor);
            cursor.moveToNext();
        }
        cursor.close();
        dataSource.close();
        return item;
    }

    public static List<CatalogCategory> getAll(Context context) {
        List<CatalogCategory> result = new ArrayList<CatalogCategory>();
        DataSource dataSource = new DataSource(context);
        dataSource.open();
        Cursor cursor = dataSource.fetchAll(ProductCategoryTable.getInstance());
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            result.add(new CatalogCategory(dataSource, cursor));
            cursor.moveToNext();
        }
        dataSource.close();
        return result;
    }

}
